package net.thxjj.adminServer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ctg.ag.sdk.biz.AepDeviceStatusClient;
import com.ctg.ag.sdk.biz.aep_device_status.GetDeviceStatusHisInPageRequest;
import com.ctg.ag.sdk.biz.aep_device_status.GetDeviceStatusHisInPageResponse;
import net.thxjj.adminServer.dao.DeviceDao;
import net.thxjj.adminServer.entity.*;
import net.thxjj.adminServer.entity.aep.profilegc.ProfileGCInfoBean;
import net.thxjj.adminServer.entity.aep.profilegc.ProfileGCLoginBean;
import net.thxjj.adminServer.mongodao.MongoLoginHandleDao;
import net.thxjj.adminServer.mongodao.MongoProfileGCInfoDao;
import net.thxjj.adminServer.mongodao.MongoProfileGCLoginDao;
import net.thxjj.adminServer.service.IProfileGCService;
import net.thxjj.adminServer.util.ParameterMap;
import net.thxjj.sitermodel.Device;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

@Service
public class ProfileGCService implements IProfileGCService {

    @Autowired
    private DeviceDao deviceDao;

    @Autowired
    private MongoProfileGCLoginDao mongoProfileGCLoginDao;

    @Autowired
    private MongoProfileGCInfoDao mongoProfileGCInfoDao;


    @Autowired
    private MongoLoginHandleDao mongoLoginHandleDao;

    @Async("asyncExecutor")
    @Override
    public void mqAddDevLog(ProfileGCInfoBean profileGCInfoBean) {
        mongoProfileGCInfoDao.saveProfileGCInfoBean(profileGCInfoBean);
    }

    @Async("asyncExecutor")
    @Override
    public void mqAddLoginData(ProfileGCLoginBean profileGCLoginBean) {
        mongoProfileGCLoginDao.saveProfileGCLoginBean(profileGCLoginBean);
    }

    @Async("asyncExecutor")
    @Override
    public void updateDeviceData(Device device) {
        Calendar now = Calendar.getInstance();
        long curtime = now.getTime().getTime();
        now.add(Calendar.DAY_OF_MONTH, -30);
        long histime = now.getTime().getTime()+10000;
        if(histime<device.getCreateTime()){
            histime = device.getCreateTime();
        }
        AepDeviceStatusClient client = AepDeviceStatusClient.newClient()
                .appKey(Const.APPKEY).appSecret(Const.APPSECRET)
                .build();
        JSONObject param = new JSONObject();
        param.put("productId",device.getProdKey());
        param.put("deviceId",device.getDeviceId());
        param.put("begin_timestamp",histime);
        param.put("end_timestamp",curtime);
        param.put("page_size",100);
        boolean flag = true;
        String page_timestamp = "";

        do {
            try {
                GetDeviceStatusHisInPageRequest request = new GetDeviceStatusHisInPageRequest();
                param.put("page_timestamp",page_timestamp);
                request.setBody(param.toJSONString().getBytes());	//具体格式见前面请求body说明
                GetDeviceStatusHisInPageResponse statusHisInPageResponse = client.getDeviceStatusHisInPage(request);
                String body = new String(statusHisInPageResponse.getBody());
                JSONObject jsonObject = JSON.parseObject(body);
                int code = jsonObject.getIntValue("code");
                page_timestamp = jsonObject.getString("page_timestamp");
                JSONArray array = jsonObject.getJSONArray("deviceStatusList");
                if(code==0){
                    if(StringUtils.isEmpty(page_timestamp)){
                        flag = false;
                    }
                    if(array.size()>0){
                        List<ProfileGCLoginBean> profileGCLoginBeanList = new ArrayList<>();
                        List<ProfileGCInfoBean> profileGCInfoBeanList = new ArrayList<>();
                        for(int i=0;i<array.size();i++){
                            JSONObject a = array.getJSONObject(i);
                            String serviceId = a.getString("serviceId");
                            String resulet = a.getString("serviceData");
                            long timestamp = a.getLongValue("timestamp");
                            if("DeviceDataUpdateReport".equals(serviceId)){
                                ProfileGCInfoBean profileGCInfoBean = JSONObject.parseObject(resulet,ProfileGCInfoBean.class);
                                profileGCInfoBean.setDeviceId(device.getDeviceId());
                                profileGCInfoBean.setTimestamp(timestamp);
                                profileGCInfoBeanList.add(profileGCInfoBean);
                            }else if("DeviceInfoReport".equals(serviceId)){
                                ProfileGCLoginBean profileGCLoginBean = JSONObject.parseObject(resulet,ProfileGCLoginBean.class);
                                profileGCLoginBean.setDeviceId(device.getDeviceId());
                                profileGCLoginBean.setTimestamp(timestamp);
                                profileGCLoginBeanList.add(profileGCLoginBean);
                            }
                        }

                        try {
                            if(profileGCLoginBeanList.size()>0){
                                mongoProfileGCLoginDao.saveProfileGCLoginBeans(profileGCLoginBeanList);
                            }

                            if(profileGCInfoBeanList.size()>0)
                                mongoProfileGCInfoDao.saveProfileGCInfoBeans(profileGCInfoBeanList);
                        }catch (Exception e){
                            e.printStackTrace();
                        }

                    }else{
                        flag = false;
                    }
                }else {
                    flag = false;
                }



            } catch (Exception e) {
                e.printStackTrace();
                flag = false;
            }
        }
        while (flag);
        client.shutdown();
    }

    @Override
    public ProfileGCInfoBean ShadowStatus(String device_id) {
        return mongoProfileGCInfoDao.getGCInfoStatus(device_id);
    }

    @Override
    public ParameterMap isMultiLoginError(String device_id) {
        List<LoginHadleEvent> loginHandleInfo = mongoLoginHandleDao.getAllLoginHandleInfo(device_id);
        long timestamp = 0;
        long value = 0;
        if(loginHandleInfo==null || loginHandleInfo.size()==0){
            List<ProfileGCLoginBean> list = mongoProfileGCLoginDao.getLoginInfoByTime(device_id,0);
            if(list.size()>1){
                value = 1;
                timestamp = list.get(list.size()-1).getTimestamp();
            }
        }else{
            long a = loginHandleInfo.get(loginHandleInfo.size()-1).getTimestamp();
            List<ProfileGCLoginBean> list = mongoProfileGCLoginDao.getLoginInfoByTime(device_id,a);
            if(list.size()>0){
                value = 1;
                timestamp = list.get(list.size()-1).getTimestamp();
            }
        }

        ParameterMap map = new ParameterMap();
        map.put("datasetId","multlogin");
        map.put("value",value);
        map.put("timestamp",timestamp);
        return map;
    }

    @Override
    public ProfileGCLoginBean ShadowLoginStatus(String device_id) {
        return mongoProfileGCLoginDao.getNewestLoginInfo(device_id);
    }

    @Override
    public ParameterMap HeartBeat(String device_id) {
        List<ProfileGCInfoBean> profileGCInfoBeanList = mongoProfileGCInfoDao.getAllinfoBeans(device_id);
        List<ProfileGCInfoBean> list = new ArrayList<>();
        for (int i=0;i<profileGCInfoBeanList.size();i++){
            ProfileGCInfoBean profileGCInfoBean = profileGCInfoBeanList.get(i);
            profileGCInfoBean.transToBean();
            if(profileGCInfoBean.getProtocol_Number()==1){
                if(profileGCInfoBean.getUpdateBean1()!=null && profileGCInfoBean.getUpdateBean1().isHeartBeat()){
                    list.add(profileGCInfoBean);
                }
            }else if(profileGCInfoBean.getProtocol_Number()==2){
                if(profileGCInfoBean.getUpdateBean2()!=null && profileGCInfoBean.getUpdateBean2().isHeartBeat()){
                    list.add(profileGCInfoBean);
                }
            }else if(profileGCInfoBean.getProtocol_Number()==3){
                list.add(profileGCInfoBean);
            }
        }

        long heartbeart = list.size();
        if(heartbeart<=0){
            ParameterMap map = new ParameterMap();
            map.put("datasetId","heartbeat");
            map.put("value",0);
            return map;
        }

        long set_heart_time;
        Device device = deviceDao.getDeviceInfo(device_id);
        if(device.getHeartTime()<=0){
            set_heart_time = 1200;
        }else {
            set_heart_time = device.getHeartTime();
        }
        long heartbeart_lilun = 0;
        long heartlv = 0;
        ProfileGCInfoBean data = list.get(0);
        if(data!=null){
            long timelong = data.getTimestamp();
            long cur_timelong = System.currentTimeMillis();
            if(cur_timelong>timelong){
                long a  = cur_timelong - timelong;
                heartbeart_lilun = (a/(set_heart_time*60000))+1;
            }
        }
        if(heartbeart>heartbeart_lilun){
            heartlv =100;
        }else{
            heartlv = heartbeart * 100 / heartbeart_lilun;
        }
        ParameterMap map = new ParameterMap();
        map.put("datasetId","heartbeat");
        map.put("value",heartlv);
        return map;
    }

    @Override
    public List<List<Object>> getLoginErrList(String device_id) {
        List<LoginHadleEvent> list =  mongoProfileGCLoginDao.getLoginHandleWithLog(device_id);
        List<List<Object>> listLogin = new ArrayList<>();
        for (LoginHadleEvent map:list) {
            long ad = map.getUserId();
            long value = 1;
            if(ad>0){
                value = 2;
            }
            long timestamp = map.getTimestamp();
            List<Object> lista = new ArrayList<>();
            lista.add(timestamp);
            lista.add(value);
            listLogin.add(lista);
        }
        return listLogin;
    }

    @Override
    public List<ProfileGCInfoBean> getInfoList(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getInfoByTime(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getSnrStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getSnrStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getRsrpStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getRsrpStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getRsrqStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getRsrqStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getCsqStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getCsqStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getPciStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getPciStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getTacStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getTacStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getEclStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getEclStatic(device_id,start_time,end_time);
    }

    @Override
    public StaticBean getEarfcnStatic(String device_id, long start_time, long end_time) {
        return mongoProfileGCInfoDao.getEarfcnStatic(device_id,start_time,end_time);
    }

    @Override
    public List<StatusBean> getJsonDataAtTime(String device_id, long start_time, long end_time) {
        List<ProfileGCLoginBean> list_logindata = mongoProfileGCLoginDao.getLoginDataAtTime(device_id,start_time,end_time);

        List<ProfileGCInfoBean> list_infoData = mongoProfileGCInfoDao.getInfoByTime(device_id,start_time,end_time);


        List<StatusBean> list = new ArrayList<StatusBean>();

        for(int i=0;i<list_logindata.size();i++){
            ProfileGCLoginBean profileLog = list_logindata.get(i);
            StatusBean statusBean = new StatusBean();
            String content = JSON.toJSONString(profileLog);
            statusBean.setEventContent(content);
            statusBean.setServiceId(5);
            statusBean.setTimestamp(profileLog.getTimestamp());
            list.add(statusBean);
        }


        for(int i=0;i<list_infoData.size();i++){
            ProfileGCInfoBean profileGCInfoBean = list_infoData.get(i);
            StatusBean statusBean = new StatusBean();
            String content = JSON.toJSONString(profileGCInfoBean);
            statusBean.setEventContent(content);
            statusBean.setServiceId(6);
            statusBean.setTimestamp(profileGCInfoBean.getTimestamp());
            list.add(statusBean);
        }
        sortList(list);

        return list;
    }

    @Override
    public List<ProfileGCInfoBean> getInfoAlarmList(String device_id, long start_time, long end_time) {
        List<ProfileGCInfoBean> listinit =  mongoProfileGCInfoDao.getInfoByTime(device_id,start_time,end_time);
        List<ProfileGCInfoBean> list = new ArrayList<>();
        for(int i=0;i<listinit.size();i++){
            ProfileGCInfoBean profileGCInfoBean = listinit.get(i);
            profileGCInfoBean.transToBean();
            if(profileGCInfoBean.getProtocol_Number()==1 && profileGCInfoBean.getUpdateBean1()!=null){
                if(profileGCInfoBean.getUpdateBean1().isDismantle()
                 ||profileGCInfoBean.getUpdateBean1().isLifeStop()
                 ||profileGCInfoBean.getUpdateBean1().isLowBattery()
                ||profileGCInfoBean.getUpdateBean1().isSDComAbnormal()
                ||profileGCInfoBean.getUpdateBean1().isLocalTestAlarm()
                ||profileGCInfoBean.getUpdateBean1().isSmokeAlarm()
                ||profileGCInfoBean.getUpdateBean1().isSensorFault()){
                    list.add(profileGCInfoBean);
                }


            }else if(profileGCInfoBean.getProtocol_Number()==2 && profileGCInfoBean.getUpdateBean2()!=null){
                if(profileGCInfoBean.getUpdateBean2().isLocalTestAlarm()
                ||profileGCInfoBean.getUpdateBean2().isRemoteTestAlarm()
                ||profileGCInfoBean.getUpdateBean2().isLowBattery()
                ||profileGCInfoBean.getUpdateBean2().isLifeStop()
                ||profileGCInfoBean.getUpdateBean2().isSDComAbnormal()
                ||profileGCInfoBean.getUpdateBean2().isGasAlarm()
                ||profileGCInfoBean.getUpdateBean2().isGasSensorFault()
                ||profileGCInfoBean.getUpdateBean2().isCoAlarm()
                ||profileGCInfoBean.getUpdateBean2().isCoSensorFault()){
                    list.add(profileGCInfoBean);
                }


            }else if(profileGCInfoBean.getProtocol_Number()==3 && profileGCInfoBean.getUpdateBean3()!=null){
                long status = profileGCInfoBean.getUpdateBean3().getDevice_status();
                switch ((int)status){
                    case 1:
                    case 3:
                    case 6:
                    case 9:
                    case 10:
                        list.add(profileGCInfoBean);
                        break;
                }

            }



        }

        return list;
    }

    @Override
    public ParameterMap getInfoStatusList(String device_id, long start_time, long end_time) {
        List<ProfileGCInfoBean> listinit =  mongoProfileGCInfoDao.getInfoByTime(device_id,start_time,end_time);
        List<List<Object>> listtime = new ArrayList<>();

        long public_status = 0,smoke_status=0,gas_status=0,co_status=0;


        for (int i=0;i<listinit.size();i++){
            ProfileGCInfoBean profileGCInfoBean = listinit.get(i);
            profileGCInfoBean.transToBean();
            List<Object> time = new ArrayList<>();
            time.add(profileGCInfoBean.getTimestamp());
            time.add(profileGCInfoBean.getProtocol_Number());
            time.add(profileGCInfoBean);
            listtime.add(time);
            if(profileGCInfoBean.getProtocol_Number()==1){
                public_status++;
                smoke_status++;
            }else if(profileGCInfoBean.getProtocol_Number()==2){
                public_status++;
                gas_status++;
                co_status++;
            }else if(profileGCInfoBean.getProtocol_Number()==3){
                public_status++;
            }

        }

        ParameterMap parameterMap = new ParameterMap();
        parameterMap.put("list",listtime);
        parameterMap.put("public_status",public_status);
        parameterMap.put("smoke_status",smoke_status);
        parameterMap.put("gas_status",gas_status);
        parameterMap.put("co_status",co_status);
        return parameterMap;
    }


    private void sortList(List<StatusBean> list) {
        if (list.size() <= 1) {

        } else {
            for (int i = 0; i < list.size() - 1; i++) {
                for (int j = 0; j < list.size() - 1 - i; j++) {
                    if (list.get(j).getTimestamp() < list.get(j+1).getTimestamp()) {
                        StatusBean statusBean1 = new StatusBean();
                        statusBean1.setTimestamp(list.get(j).getTimestamp());
                        statusBean1.setServiceId(list.get(j).getServiceId());
                        statusBean1.setEventContent(list.get(j).getEventContent());

                        StatusBean statusBean2 = new StatusBean();
                        statusBean2.setTimestamp(list.get(j+1).getTimestamp());
                        statusBean2.setServiceId(list.get(j+1).getServiceId());
                        statusBean2.setEventContent(list.get(j+1).getEventContent());

                        list.set(j,statusBean2);
                        list.set(j+1,statusBean1);
                    }
                }
            }

        }
    }

}
